package com.wiscamp.ninechapters.problems.infrastructure.repositories;

import com.wiscamp.ninechapters.common.core.CollectionHelper;
import com.wiscamp.ninechapters.problems.domain.models.problems.questions.*;
import com.wiscamp.ninechapters.problems.domain.models.sheets.*;
import com.wiscamp.ninechapters.problems.infrastructure.converters.SheetConverter;
import com.wiscamp.ninechapters.problems.infrastructure.mappers.sheets.SheetDetailMapper;
import com.wiscamp.ninechapters.problems.infrastructure.mappers.sheets.SheetMapper;
import com.wiscamp.ninechapters.problems.infrastructure.mappers.sheets.SheetAnswerMapper;
import com.wiscamp.ninechapters.problems.infrastructure.po.sheets.SheetAnswerPO;
import com.wiscamp.ninechapters.problems.infrastructure.po.sheets.SheetDetailPO;
import com.wiscamp.ninechapters.problems.infrastructure.po.sheets.SheetPO;
import cube.common.core.CollectionUtils;
import cube.ddd.utils.PersistenceUtils;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class SheetBuilder {

    private final Logger logger = LoggerFactory.getLogger(SheetBuilder.class);

    private final SheetMapper sheetMapper;

    private final SheetDetailMapper sheetDetailMapper;

    private final SheetAnswerMapper sheetAnswerMapper;

    private final ProblemBuilder problemBuilder;

    public SheetBuilder(SheetMapper sheetMapper, SheetDetailMapper sheetDetailMapper, SheetAnswerMapper sheetAnswerMapper, ProblemBuilder problemBuilder) {
        this.sheetMapper = sheetMapper;
        this.sheetDetailMapper = sheetDetailMapper;
        this.sheetAnswerMapper = sheetAnswerMapper;
        this.problemBuilder = problemBuilder;
    }

    // region PO
    public SheetPO getSheetPO(long sheetId) {
        var sheetPO = PersistenceUtils.findById(sheetId, sheetMapper::findById);
        loadSheetPODetails(sheetPO);
        return sheetPO;
    }

    public void loadSheetPODetails(SheetPO sheetPO) {
        if (Objects.nonNull(sheetPO)) {
            var sheetDetailPOs = getSheetDetailPOs(sheetPO.getSheetId());
            var detailIds = sheetDetailPOs.stream().map(SheetDetailPO::getDetailId).collect(Collectors.toList());
            var textExtensionPOs = getSheetAnswerPOs(detailIds);
            for (var detail : sheetDetailPOs) {
                var textExtensions = textExtensionPOs.stream().filter(e->e.getSheetDetailId() == detail.getDetailId()).collect(Collectors.toList());
                detail.setSheetAnswers(textExtensions);
            }
            sheetPO.setDetails(sheetDetailPOs);
        }
    }

    public Collection<SheetDetailPO> getSheetDetailPOs(@Min(0) long sheetId) {
        return sheetDetailMapper.findListBySheet(sheetId);
    }

    public Collection<SheetAnswerPO> getSheetAnswerPOs(@Min(0) long detailId) {
        return sheetAnswerMapper.findListByDetail(detailId);
    }

    public Collection<SheetAnswerPO> getSheetAnswerPOs(@Min(0) Collection<Long> detailIds) {
        return sheetAnswerMapper.findListByDetails(detailIds);
    }
    // endregion

    // region converter
    public Sheet toSheet(@NotNull SheetPO sheetPO) {
        var sheet = SheetConverter.Instance.toSheet(sheetPO);
        sheet.getDetails().clear();
        for (var detailPO : sheetPO.getDetails()) {
            var sheetDetail = toSheetDetail(detailPO);
            sheet.getDetails().add(sheetDetail);
        }
        return sheet;
    }

    public SheetPO toSheetPO(@NotNull Sheet sheet) {
        var sheetPO = SheetConverter.Instance.toSheetPO(sheet);
        sheetPO.getDetails().clear();
        for (var sheetDetail : sheet.getDetails()) {
            var detailPO = toSheetDetailPO(sheetDetail);
            sheetPO.getDetails().add(detailPO);
        }
        return sheetPO;
    }

    public SheetDetailPO toSheetDetailPO(@NotNull SheetDetail sheetDetail) {
        var detailPO = SheetConverter.Instance.toSheetDetailPO(sheetDetail);
        //detailPO.getSheetAnswers().clear();
        return detailPO;
    }

    public SheetAnswerPO toSheetAnswerPO(SheetAnswer sheetAnswer) {
        return SheetConverter.Instance.toSheetAnswerPO(sheetAnswer);
    }

    public SheetDetail toSheetDetail(@NotNull SheetDetailPO sheetDetailPO) {
        SheetDetail sheetDetail = null;
        var question = problemBuilder.getQuestion(sheetDetailPO.getQuestionId());
        var sheetAnswerPOs = sheetDetailPO.getSheetAnswers();
        var sheetAnswers = CollectionHelper.convertToArrayList(sheetAnswerPOs, this::toSheetAnswer);

        if (question instanceof TrueFalseQuestion) {
            // 10 判断问题
            sheetDetail = new TrueFalseSheetDetail();
            ((TrueFalseSheetDetail) sheetDetail).setQuestion((TrueFalseQuestion) question);
            ((TrueFalseSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof MultipleChoiceQuestion) {
            // 20 单选问题
            sheetDetail = new MultipleChoiceSheetDetail();
            ((MultipleChoiceSheetDetail) sheetDetail).setQuestion((MultipleChoiceQuestion) question);
            ((MultipleChoiceSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof MultipleSelectionQuestion) {
            // 30 多选问题
            sheetDetail = new MultipleSelectionSheetDetail();
            ((MultipleSelectionSheetDetail) sheetDetail).setQuestion((MultipleSelectionQuestion) question);
            ((MultipleSelectionSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof ColumnCalculationQuestion) {
            // 116 列式计算问题
            sheetDetail = new ColumnCalculationSheetDetail();
            ((ColumnCalculationSheetDetail) sheetDetail).setQuestion((ColumnCalculationQuestion) question);
            ((ColumnCalculationSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof GeometryCalculationQuestion) {
            // 117 几何计算问题
            sheetDetail = new GeometryCalculationSheetDetail();
            ((GeometryCalculationSheetDetail) sheetDetail).setQuestion((GeometryCalculationQuestion) question);
            ((GeometryCalculationSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof GeometryCompletionQuestion) {
            // 118 几何填空问题
            sheetDetail = new GeometryCompletionSheetDetail();
            ((GeometryCompletionSheetDetail) sheetDetail).setQuestion((GeometryCompletionQuestion) question);
            ((GeometryCompletionSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof CompletionQuestion) {
            // 50 填空问题
            sheetDetail = new CompletionSheetDetail();
            ((CompletionSheetDetail) sheetDetail).setQuestion((CompletionQuestion) question);
            ((CompletionSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof WordQuestion) {
            // 119 文字应用
            sheetDetail = new WordSheetDetail();
            ((WordSheetDetail) sheetDetail).setQuestion((WordQuestion) question);
            ((WordSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof UnitConversionQuestion) {
            // 120 单位转换
            sheetDetail = new UnitConversionSheetDetail();
            ((UnitConversionSheetDetail) sheetDetail).setQuestion((UnitConversionQuestion) question);
            ((UnitConversionSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof EquationInequalityQuestion) {
            // 121 解方程
            sheetDetail = new EquationInequalitySheetDetail();
            ((EquationInequalitySheetDetail) sheetDetail).setQuestion((EquationInequalityQuestion) question);
            ((EquationInequalitySheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof ProveQuestion) {
            // 122 推理证明
            sheetDetail = new ProveSheetDetail();
            ((ProveSheetDetail) sheetDetail).setQuestion((ProveQuestion) question);
            ((ProveSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof RatioProportionQuestion) {
            // 123 比与比例问题
            sheetDetail = new RatioProportionSheetDetail();
            ((RatioProportionSheetDetail) sheetDetail).setQuestion((RatioProportionQuestion) question);
            ((RatioProportionSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof ProbabilityCalculationQuestion) {
            // 124 概率计算问题
            sheetDetail = new ProbabilityCalculationSheetDetail();
            ((ProbabilityCalculationSheetDetail) sheetDetail).setQuestion((ProbabilityCalculationQuestion) question);
            ((ProbabilityCalculationSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof StatisticsCalculationQuestion) {
            // 125 统计问题
            sheetDetail = new StatisticsCalculationSheetDetail();
            ((StatisticsCalculationSheetDetail) sheetDetail).setQuestion((StatisticsCalculationQuestion) question);
            ((StatisticsCalculationSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof FactorsMultiplesQuestion) {
            // 126 因数复数问题
            sheetDetail = new FactorsAndMultiplesSheetDetail();
            ((FactorsAndMultiplesSheetDetail) sheetDetail).setQuestion((FactorsMultiplesQuestion) question);
            ((FactorsAndMultiplesSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else if (question instanceof CalculationQuestion) {
            // 40 计算问题
            sheetDetail = new CalculationSheetDetail();
            ((CalculationSheetDetail) sheetDetail).setQuestion((CalculationQuestion) question);
            ((CalculationSheetDetail) sheetDetail).setSheetAnswers(sheetAnswers);
        } else {
            logger.error("无法匹配适合的答题卡明细问题类型。答题卡明细编号: {}/{}", question.getQuestionId(), question);
        }

        if (Objects.isNull(sheetDetail)) {
            logger.error("Failed to create sheet detail. The sheet detail id is {}", sheetDetailPO.getDetailId());
            return null;
        }

        if (Objects.isNull(sheetDetailPO.getQuestionBeginTime())) {
            logger.warn("The field of itemBeginTime is null. The sheet detail id is {}/{}", sheetDetail.getSheetId(), sheetDetail.getDetailId());
        }
        if (Objects.isNull(sheetDetailPO.getQuestionEndTime())) {
            logger.warn("The field of itemEndTime is null.The sheet detail id is {}/{}", sheetDetail.getSheetId(), sheetDetail.getDetailId());
        }

        sheetDetail.setSheetAnswers(sheetAnswers);
        BeanUtils.copyProperties(sheetDetailPO, sheetDetail);
        return sheetDetail;
    }

    public SheetAnswer toSheetAnswer(SheetAnswerPO textExtensionPO) {
        return SheetConverter.Instance.toSheetAnswer(textExtensionPO);
    }

    // endregion

    public Sheet getSheet(long sheetId) {
        // get Sheet
        var sheetPO = getSheetPO(sheetId);
        if (Objects.isNull(sheetPO)) return null;
        return toSheet(sheetPO);
    }

    public SheetDetail getSheetDetail(long taskId, long problemId, long questionId) {
        var sheetDetailPOs = sheetDetailMapper.findByTaskAndQuestion(taskId, problemId, questionId);
        if (CollectionUtils.isEmpty(sheetDetailPOs)) return null;
        return toSheetDetail(sheetDetailPOs.stream().findFirst().orElse(null));
    }

    public Collection<SheetAnswer> getSheetAnswers(long sheetDetailId) {
        var textExtensions = sheetAnswerMapper.findListByDetail(sheetDetailId);
        return CollectionUtils.toArrayList(textExtensions, SheetConverter.Instance::toSheetAnswer);
    }
}
